package exception

import (
	"fmt"
	"strings"
)

type ExceptionError struct {
	Code       int
	Message    string
	Level      ErrorLevel // 错误级别
	Location   Location   // 错误发生的位置
	StackTrace []string
}
type Location struct {
	File string
	Line int
	Col  int
}

// ErrorLevel 定义错误严重级别
type ErrorLevel int

const (
	LevelFatal   ErrorLevel = iota // 致命错误，需要立即终止
	LevelError                     // 错误
	LevelWarning                   // 警告
)

// Outputter 定义包管理器的输出接口
type Outputter interface {
	// Warn 输出警告信息
	Warn(message string, args ...interface{})
	// Error 输出错误信息
	Error(message string, args ...interface{})
	// Fatal 输出致命错误并退出
	Fatal(message string, args ...interface{})
}

func (e *ExceptionError) Error() string {
	// 配置日志不显示时间戳和其他前缀
	// log.SetFlags(0)
	var builder strings.Builder
	builder.WriteString(fmt.Sprintf("[错误][%04d]%s ", e.Code, e.Message))
	return builder.String()
}

// Warn 输出警告信息
func WarnError(message string, args ...interface{}) *ExceptionError {
	resutlInfo := &ExceptionError{
		Message: message,
		Level:   LevelWarning,
		Location: Location{
			File: "",
			Line: 0,
			Col:  0,
		},
	}
	if len(args) > 0 {
		resutlInfo.Code = args[0].(int) // 假设第一个参数是错误代码
	}
	if len(args) > 1 && args[1] != nil {
		resutlInfo.Location = args[1].(Location) // 假设第二个参数是错误位置
	}
	return resutlInfo
}

// Error 输出错误信息
func Error(message string, args ...interface{}) *ExceptionError {
	resutlInfo := &ExceptionError{
		Message: message,
		Level:   LevelError,
		Location: Location{
			File: "",
			Line: 0,
			Col:  0,
		},
	}
	if len(args) > 0 {
		resutlInfo.Code = args[0].(int) // 假设第一个参数是错误代码
	}
	if len(args) > 1 && args[1] != nil {
		resutlInfo.Location = args[1].(Location) // 假设第二个参数是错误位置
	}
	return resutlInfo
}

// Fatal 输出致命错误并退出
func FatalError(message string, args ...interface{}) *ExceptionError {
	resutlInfo := &ExceptionError{
		Message: message,
		Level:   LevelFatal,
		Location: Location{
			File: "",
			Line: 0,
			Col:  0,
		},
	}
	if len(args) > 0 {
		resutlInfo.Code = args[0].(int) // 假设第一个参数是错误代码
	}
	if len(args) > 1 && args[1] != nil {
		resutlInfo.Location = args[1].(Location) // 假设第二个参数是错误位置
	}
	return resutlInfo
}
